package com.GreenIce.android.UI;

import java.lang.reflect.Field;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.GreenIce.android.R;
import com.GreenIce.android.datastructure.ConfigData;
import com.GreenIce.android.datastructure.GameLevel;
import com.GreenIce.android.datastructure.Strike;
import com.GreenIce.android.util.DirectionIdentifier;
import com.GreenIce.android.util.DistanceSensor;
import com.GreenIce.android.util.HeadSetManager;
import com.GreenIce.android.util.SoundEffectManager;

/**
 * 游戏进行界面...
 * @author Jas0n
 *
 */
public class PlayingView {
	Activity activity;
	GameLevel gl;
	ProgressBar pb;
	View base;
	TextView gameStatus;
	ImageButton btPause;
	ImageButton btRestart;
	
	SoundEffectManager sem;
	
	
	GamePlaying gp;
	MediaPlayer mp;
	
	State state;
	int score,failed;
	public PlayingView(Activity activity) {
		this.activity = activity;
	}
	
	public View show(GameLevel gl) {
		LayoutInflater inflater = activity.getLayoutInflater();
		base = inflater.inflate(R.layout.game_playing, null);
		activity.setContentView(base);
		this.gl = gl;
		pb = (ProgressBar) base.findViewById(R.id.progressBar1);
		gameStatus = (TextView) base.findViewById(R.id.gamestatus);
		btPause = (ImageButton) base.findViewById(R.id.pause); 
		btRestart = (ImageButton) base.findViewById(R.id.restart);
		
		//sound effect
		sem = SoundEffectManager.getInstance();			
		
		//pause button
		btPause.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				pause();
				showDlg();
			}
		});
		//restart button
		btRestart.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				if (gp != null){
					pb.setProgress(0);
					failed = 0;
					gp.cancel(true);//failed 为0的cancle不会导致界面跳转
					if (mp != null){
//						if (mp.isPlaying())mp.stop();
						mp.release();
					}
					startGame();
				}
			}
		});
		startGame();
		
		return base;
	}
	public void showDlg(){
//		LayoutInflater inflater=(LayoutInflater)activity.getLayoutInflater();
//	    View layout=inflater.inflate(R.layout.dlg,null);
//	    ImageButton resume = (ImageButton) layout.findViewById(R.id.imageButton1);
//	    ImageButton back = (ImageButton) layout.findViewById(R.id.imageButton2);
//	    resume.setOnClickListener(new OnClickListener() {
//			
//			@Override
//			public void onClick(View arg0) {
//				// TODO Auto-generated method stub
//				if(HeadSetManager.getInstance().isPlug()){
//					resume();
//				}
//				else{
//					Dialog adialog = new AlertDialog.Builder(activity)
//					  .setTitle(R.string.dlg)
//					  .setMessage(R.string.ear)
//					  .setPositiveButton(R.string.yes,new DialogInterface.OnClickListener() {
//						public void onClick(DialogInterface dialog, int whichButton){
//						}
//					  })
//					  .create();
//					adialog.show();
//				}
//			}
//		});
//	    
//	    back.setOnClickListener(new OnClickListener() {
//			
//			@Override
//			public void onClick(View v) {
//				// TODO Auto-generated method stub
//				if (mp != null) mp.release();
//				int wid = ConfigData.getInstance().curWorld;
//				UImanager.getInstance().setChooseLevelView(wid);
//			}
//		});
//	    
//	    Dialog adlg = new Dialog(activity);
//	    adlg.setContentView(layout);
//	    adlg.show();
		AlertDialog dlg =new AlertDialog.Builder(activity)
		.setTitle(R.string.menu)
		.setNegativeButton(R.string.resume, new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				try { 
					Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing"); 
					field.setAccessible(true); 
					field.set(dialog, false);
				} 
				catch (Exception e) { 
					e.printStackTrace(); 
				} 
				if(HeadSetManager.getInstance().isPlug()){
					try {
					      Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing");
					      field.setAccessible(true);
					      field.set(dialog, true);
					} 
					catch (Exception e) {
					      e.printStackTrace();
					}
				    dialog.dismiss();
					resume();
				}
				else{
					Dialog adialog = new AlertDialog.Builder(activity)
					  .setTitle(R.string.warning)
					  .setMessage(R.string.ear)
					  .setPositiveButton(R.string.yes,new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int whichButton){
						}
					  })
					  .create();
					adialog.show();
				}
			}
		})
		.setPositiveButton(R.string.back, new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				if (mp != null) mp.release();
				int wid = ConfigData.getInstance().curWorld;
				try {
				      Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing");
				      field.setAccessible(true);
				      field.set(dialog, true);
				} 
				catch (Exception e) {
				      e.printStackTrace();
				}
				dialog.dismiss();
				UImanager.getInstance().setChooseLevelView(wid);
				
			}
		})
//		.setPositiveButton("主界面", new DialogInterface.OnClickListener() {
//			
//			@Override
//			public void onClick(DialogInterface dialog, int which) {
//				if (mp != null) mp.release();
//				try {
//				      Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing");
//				      field.setAccessible(true);
//				      field.set(dialog, true);
//				} 
//				catch (Exception e) {
//				      e.printStackTrace();
//				}
//				dialog.dismiss();
//				UImanager.getInstance().setMainView();								
//			}
//		})
		.create();
		dlg.setCanceledOnTouchOutside(false);
		dlg.show();
	}
	/**
	 * 开始游戏
	 */
	void startGame(){
		//intro sound
//		MediaPlayer intro = MediaPlayer.create(activity,gl.sounds_resid.get(0));
//		intro.setOnCompletionListener(new OnCompletionListener() {
//			
//			@Override
//			public void onCompletion(MediaPlayer mp) {
//				if (gp != null) gp.cancel(true);
//			}
//		});
//		intro.start();
		SoundEffectManager.releaseMediaplayer();
		
		gp = new GamePlaying();
		gp.execute();
		
		//init...
		state = new State();
		state.setState(false);
		score = 0;
		failed = 0;
	}
	/**
	 * 暂停游戏
	 */
	protected void pause() {
		DistanceSensor.disable();
		HeadSetManager.disable();
		synchronized (state) {
			if (mp != null && mp.isPlaying()) 
				mp.pause();
			state.setState(true);
		}
	}
	/**
	 * 恢复游戏
	 */
	protected void resume() {
		 DistanceSensor.enable();
		 HeadSetManager.enable();
		synchronized (state) {
			if (mp != null){
				mp.start();
			}
			state.setState(false);
		}
	}
	/**
	 * 获取时间状态因子,0为暂停,1为正常
	 * @return
	 */
	protected int getStateFactor(){
		synchronized (state){
			if (state.getState()){
				return 0;
			} else 
				return 1;
		}
	}
	
	private class GamePlaying extends AsyncTask<GameLevel, Integer, Integer>{
		static final int LOAD = 0;
		static final int PLAY = 1;
		static final int STOP = 2;
		static final int WAITING = 3;
		static final int PLAYING = 4;
		
		static final int TIME_SPAN = 100;
		
		long base_time;
		int process;
		int playingLastTimeStamp;
		int playingHoldTime;
		@Override
		protected void onPreExecute() {
			pb.setMax(gl.tolTime);
			pb.setProgress(0);	
			base_time = System.currentTimeMillis();
			process = 0;
			playingLastTimeStamp = -1;
			playingHoldTime = 0;
			super.onPreExecute();
		}
		@Override
		protected Integer doInBackground(GameLevel... gamelevels) {			
			int curTime = 0;			
			for(int i = 0 ; i < gl.m; i++){
				Strike s = gl.strikes.get(i);
				
				//load
				publishProgress(i,LOAD);
				
				//waiting.
				int waitedTime = 0;
				while (waitedTime < s.pre_time){
					int t = getTime();					
					sleep(TIME_SPAN);
					if (isCancelled()) {
						Log.i("doInBackground", "canceled while waiting!");
						return 0;
					}
					waitedTime += (getTime() - t)*getStateFactor();//not change while it pause
					publishProgress(i,WAITING,waitedTime);
				}
				
				//play
				publishProgress(i,PLAY);
				
				//playing
				int playedTime = 0;
				while (playedTime < s.last_time){
					int t = getTime();
					sleep(TIME_SPAN);
					if (isCancelled()) {
						Log.i("doInBackground", "canceled while playing!");
						return 0;
					}
					playedTime += (getTime() - t)*getStateFactor();//not change while it pause
					publishProgress(i,PLAYING,playedTime);
				}
				
				//stop
				publishProgress(i,STOP);
				if (isCancelled()) {
					Log.i("doInBackground", "canceled afer STOP!");
					return 0;
				}
			}
			return 1;
		}
		int getTime(){
			return (int)(System.currentTimeMillis()-base_time);
		}
		int sleep(int t){
			try {
				Thread.sleep(t);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return t;
		}
		@Override
		protected void onProgressUpdate(Integer... values) {
			int sid = values[0];
			Strike s = gl.strikes.get(sid);
			switch (values[1]){
			case LOAD:{
				mp = MediaPlayer.create(activity,gl.sounds_resid.get(s.sound_id));
				if (!s.isTip())
					mp.setLooping(true);
				break;
			}
			case PLAY:{
				process += gl.strikes.get(sid).pre_time;
				playingHoldTime = 0;
				playingLastTimeStamp = -1;
				mp.start();
				break;
			}
			case STOP:{
				process += gl.strikes.get(sid).last_time;
				
				if (playingHoldTime > s.beat_time){
					if (s.isValid()){//有效音
						score += playingHoldTime;
						//根据不同的表现增加得分.
						if (playingHoldTime > s.beat_time*2 || playingHoldTime > s.last_time * 0.9)
							sem.playExcellentSound();
						else if (playingHoldTime > s.beat_time*1.5 || playingHoldTime > s.last_time * 0.75){
							sem.playGreatSound();
						} else 
							sem.playGoodSound();
					} 
					if (s.isFool()){
						score -= playingHoldTime;
						sem.playFoolSound();
					}
				} else {
					if (s.isValid()){
						failed ++;
						sem.playFailSound();
					} 
					if (s.isFool()){
						playingHoldTime = s.last_time - playingHoldTime;
						score += playingHoldTime;
						//根据不同的表现增加得分.
						if (playingHoldTime > s.beat_time*2 || playingHoldTime > s.last_time * 0.9)
							sem.playExcellentSound();
						else if (playingHoldTime > s.beat_time*1.5 || playingHoldTime > s.last_time * 0.75){
							sem.playGreatSound();
						} else 
							sem.playGoodSound();
					}
				}
				if (failed == 3){
					cancel(true);
				}
				mp.stop();
				mp.release();
				
				break;
			}
			case WAITING:{
				int waitedTime = values[2];
				pb.setProgress(process + waitedTime);
				gameStatus.setText("state:WAITING-->"+waitedTime+"/"+s.pre_time
       					+"\nsound_id:"+sid+"/"+gl.m
       					+"\nscore:"+score
       					+"\nfailed:"+failed
       					+"\ntarget_dir:"+s.dir_id
       					+"\ndirection:"+DirectionIdentifier.getCurrentDirection());
				break;
			}
			case PLAYING:{
				int playedTime = values[2];
				pb.setProgress(process + playedTime);
				int curDir = DirectionIdentifier.getCurrentDirection();
				if (curDir == s.dir_id)
					playingHoldTime += playedTime - playingLastTimeStamp;
				playingLastTimeStamp = playedTime;				
				gameStatus.setText("state:PLAYING-->"+playedTime+"/"+s.last_time
       					+"\nsound_id:"+sid+"/"+gl.m
       					+"\nscore:"+score
       					+"\nfailed:"+failed
       					+"\ntarget_dir:"+s.dir_id
       					+"\ndirection:"+curDir
       					+"\nholding:"+playingHoldTime+"/"+s.last_time);
				break;
			}
			default:
				Log.e("onProgressUpdate","ERROR OPERATOR");
			}
			super.onProgressUpdate(values);
		}
		@Override
		protected void onPostExecute(Integer result) {
			Log.v("onPostExecute","result:"+result+",Score:"+score+",Star:"+(3-failed));
			if (result == 1)
				UImanager.getInstance().setGameOverView(score,3-failed);
			super.onPostExecute(result);
		}
		@Override
		protected void onCancelled() {
			Log.v("onCancelled","Score:"+score+",Star:"+(3-failed));
			if (failed == 3)
				UImanager.getInstance().setGameOverView(score,3-failed);
			super.onCancelled();
		}
	}
	private class State{
		boolean isPause;
		void setState(boolean isPause){
			this.isPause = isPause;
		}
		boolean getState(){
			return isPause;
		}
	}
}
